package cn.js189.uqc.task;

import cn.js189.common.constants.InvoiceConstant;
import cn.js189.common.util.helper.UUIDHelper;
import cn.js189.uqc.common.WxService;
import cn.js189.uqc.mapper.CheckInfoMapper;
import cn.js189.uqc.redis.RedisOperation;
import cn.js189.uqc.util.RedisUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import javax.annotation.Resource;
import java.util.List;

/**
 * 公众号对已经授权的发票插入用户卡包定时任务
 */
@Slf4j
public class WxCardTask implements Runnable{

	@Resource
	private WxService wxService;
	@Resource
	private CheckInfoMapper checkInfoMapper;
	@Resource
	private RedisOperation redisOperation;
	
	public WxCardTask(WxService wxService, CheckInfoMapper checkInfoMapper,RedisOperation redisOperation) {
		this.wxService = wxService;
		this.checkInfoMapper = checkInfoMapper;
		this.redisOperation = redisOperation;
	}
	
	@Override
	public void run() {

		log.info("微信插卡定时任务启动...");

		// 考虑数据量大的情况下，做分页/分片处理
		List<String> invoiceIds = this.checkInfoMapper.selectAllAuthSuccessInvoiceId();

		if (null != invoiceIds && !invoiceIds.isEmpty()) {
			log.info("微信插卡定时任务查询出数据:{}", invoiceIds.size());
			
			for (String invoiceId : invoiceIds) {
				log.info("发票【{}】已经授权完成,开始进行插卡操作!", invoiceId);
				
				// 加锁
				String lockValue = UUIDHelper.getUUID();
				String lockKey = InvoiceConstant.WX_CARD_INSERT_PREFIX + invoiceId;
				String lockResult = RedisUtil.tryLock(redisOperation, "电子发票插卡", lockKey, lockValue);
				
				// 获取锁失败
				if (!StringUtils.equals(lockResult, RedisUtil.LOCK_SUCCESS)) {
					continue;
				}
				
				try {
					// 公众号插卡
					this.wxService.toInsertInvoice(invoiceId, "", "", null);
				} catch (Exception e) {
					log.info("发票【{}】插卡任务异常 {}", invoiceId, e.getMessage());
				}
				
				RedisUtil.unlock(redisOperation, "电子发票插卡", lockKey, lockValue);
				
			}
		}
	}

}
